package com.adee.design.create.factory;

/*
 * 工厂方法模式  开闭原则：对扩展开放，对修改关闭
 * 四元素：抽象工厂、具体工厂、抽象产品呢、具体产品。
 * 在具体的工厂中创建具体的产品。
 * 规避了简单工厂违反开闭原则的缺点，但是一个具体工厂只有一个创建方法，只能创建一款产品，
 * 每新增一款产品就要创建一个具体工厂，有点啰嗦。
 * 可以在抽象工厂（抽象类或接口）中定义多个抽象创建方法，这样，一个工厂就可以生产一种类型（多种款式）的产品了，
 * 前提是一旦类型确定了，款式就要确定，若后期有新增款式，就要修改代码，违反开闭原则，回过头来倒不如使用工厂方法模式了。
 *
 * */
public class FactoryMethodTest {
    public static void main(String[] args) {
        AbstractBmwCarFactory factory = new X7SuvGrayBmwCarFactory();
        IBmwCar car = factory.createCar();
        car.test();
        factory = new The7CommonBlackBmwCarFactory();
        IBmwCar car2 = factory.createCar();
        car2.test();
    }

    // 抽象工厂
    static abstract class AbstractBmwCarFactory {
        public IBmwCar createCar() {
            System.out.println("生产一台宝马车：");
            return doCreateCar();
        }
        protected abstract IBmwCar doCreateCar();
    }

    // 具体工厂1（生产X7灰色）
    static class X7SuvGrayBmwCarFactory extends AbstractBmwCarFactory {
        @Override
        protected IBmwCar doCreateCar() {
            return new X7SuvGrayBmwCar();
        }
    }

    // 具体工厂2（生产7系黑色）
    static class The7CommonBlackBmwCarFactory extends AbstractBmwCarFactory {
        @Override
        protected IBmwCar doCreateCar() {
            return new The7CommonBlackBmwCar();
        }
    }

    /*
     * 抽象产品（宝马车）
     * 类型 suv、轿车common、mpv
     * 系列 7系、5系、3系、X7、X5、X3
     * 颜色 黑色、白色、灰色
     *
     * 产品特点：只要类型、系列、颜色有一个不同，就算一个新产品，就要新建一个类
     * */
    interface IBmwCar {
        public abstract void engine(); // 发动机
        public abstract void platform(); // 车架
        public abstract void decoration(); // 装饰
        public abstract void assemble(); // 装配
        public abstract void test(); // 测试
    }

    // 具体产品1（灰色X7 suv）
    static class X7SuvGrayBmwCar implements IBmwCar {

        @Override
        public void engine() {
            System.out.println("宝马X7 Suv 灰色动机");
        }

        @Override
        public void platform() {
            System.out.println("宝马X7 Suv 灰色架构");
        }

        @Override
        public void decoration() {
            System.out.println("宝马X7 Suv 灰色内饰");
        }

        @Override
        public void assemble() {
            System.out.println("宝马X7 Suv 灰色装配");
        }

        @Override
        public void test() {
            System.out.println("宝马X7 Suv 灰色测试");
        }
    }
    // 具体产品2（黑色7系轿车）
    static class The7CommonBlackBmwCar implements IBmwCar {

        @Override
        public void engine() {
            System.out.println("黑色7系轿车动机");
        }

        @Override
        public void platform() {
            System.out.println("黑色7系轿车架构");
        }

        @Override
        public void decoration() {
            System.out.println("黑色7系轿车内饰");
        }

        @Override
        public void assemble() {
            System.out.println("黑色7系轿车装配");
        }

        @Override
        public void test() {
            System.out.println("黑色7系轿车测试");
        }
    }
}
